package com.zjitc.book.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.jwt.JWTUtil;
import com.zjitc.book.common.result.R;
import com.zjitc.book.dto.UserDto;
import com.zjitc.book.entity.MyUserDetails;
import com.zjitc.book.entity.Permission;
import com.zjitc.book.entity.User;
import com.zjitc.book.filter.JwtFilter;
import com.zjitc.book.mapper.UserMapper;
import com.zjitc.book.service.UserInfoService;
import com.zjitc.book.service.UserService;
import com.zjitc.book.service.impl.UserServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

//@CrossOrigin
@RestController
@RequestMapping("/api")
public class UserController {

    private static final String key = "1234565465sfdfsafgfdsagfdfs";

    @Autowired
    AuthenticationManager authManager;

    @Autowired
    UserServiceImpl userService;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    private static final Logger logger = LoggerFactory.getLogger(JwtFilter.class);

    @PostMapping("/auth/login")
    public R<Map<String,Object>> login(@RequestBody UserDto user){//Entity和DTO的区别
        System.out.println(user);
        //1、借助authManager来完成认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
        Authentication authenticate = authManager.authenticate(authenticationToken);

        //2、从authManager获取用户信息
        MyUserDetails userDetails = (MyUserDetails)authenticate.getPrincipal();
        Integer userId = userDetails.getUser().getId();
        String userName = userDetails.getUsername();
        List<String> authorities = userDetails.getAuthors();

        //2.1、把登录的用户权限存入redis
        stringRedisTemplate.opsForSet().add("user.perms:"+userId,authorities.toArray(new String[0]));

        //3、用hutool工具生成JWT令牌（token）
        Map<String,Object> map = new HashMap<>();
        map.put("userId",userId);
        map.put("username",userName);
        map.put("exp", DateUtil.currentSeconds()+60*60);
        String token = JWTUtil.createToken(map, key.getBytes());
        logger.info("Generated token: {}", token);

        //返回响应
        Map<String,Object> res = new HashMap<>();
        res.put("token",token);
        res.put("userId",userId);
        res.put("username",userName);
        res.put("permissions",authorities);
        return R.success(res,"登录成功");
    }

    @PostMapping("/auth/register")
    public Map<String,Object> register(@RequestBody UserDto user){
        Map<String,Object> result = new HashMap<>();
//        System.out.println(user);
        try {
            User newUser = userService.register(user);
            result.put("code",200);
            result.put("msg","success");
            result.put("data",newUser);
        } catch (Exception e) {
            result.put("code",500);
            result.put("msg",e.getMessage());
        }
        return result;
    }
//    使用 Spring Security 的权限控制，拥有sys:user:list权限的用户才能访问该接口
    @GetMapping("/system")
    @PreAuthorize("hasAuthority('sys:user:list')")
    public List<User> getUserList(){
        return userService.getAllUsers();
    }

    @GetMapping("/user/menu")
    public List<Permission> getMenu(){
        return userInfoService.getMenu();
    }
}
